package org.ysling.litemall.core.tenant.interceptor;
/**
 *  Copyright (c) [ysling] [927069313@qq.com]
 *  [litemall-plus] is licensed under Mulan PSL v2.
 *  You can use this software according to the terms and conditions of the Mulan PSL v2.
 *  You may obtain a copy of Mulan PSL v2 at:
 *              http://license.coscl.org.cn/MulanPSL2
 *  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 *  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 *  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *  See the Mulan PSL v2 for more details.
 */
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import org.ysling.litemall.core.tenant.handler.TenantContextHolder;
import org.ysling.litemall.db.domain.LitemallTenant;
import org.ysling.litemall.db.service.ITenantService;
import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 多租户拦截器
 *
 * preHandle()用于在将请求发送到控制器之前执行操作。此方法应返回true，以将响应返回给客户端。
 * postHandle()用于在将响应发送到客户端之前执行操作
 * afterCompletion()用于在完成请求和响应后执行操作
 *
 * @author Ysling
 */
@Component
public class TenantInterceptor implements HandlerInterceptor {

    @Autowired
    private WxMaService wxService;
    @Autowired
    private ITenantService tenantService;

    /**
     * preHandle用于在将请求发送到控制器之前执行操作。此方法应返回true，以将响应返回给客户端。
     * @param request       请求
     * @param response      响应
     * @param handler       对象
     * @return              true
     * @throws Exception    异常
     */
    @Override
    public boolean preHandle(@Nonnull HttpServletRequest request,
                             @Nonnull HttpServletResponse response,
                             @Nonnull Object handler) throws Exception {


        //获取当前请求租户
        String tenantId = TenantContextHolder.returnTenantId(false);
        if (tenantId == null){
            throw new RuntimeException("未找到授权租户");
        }

        //设置当前租户为默认租户
        TenantContextHolder.setDefaultId();
        //如果没有租户直接放行
        if (tenantService.count() == 0){
            return true;
        }

        //判断是否是默认租户，是则直接放行
        if (TenantContextHolder.isDefaultId(tenantId)) {
            return true;
        }

        //获取当前租户
        LitemallTenant tenant = tenantService.findById(tenantId);
        if (tenant == null) {
            throw new RuntimeException("未找到授权租户");
        }

        // 切换微信配置
        wxService.switchoverTo(tenant.getAppId());
        //切换租户
        TenantContextHolder.setLocalTenantId(tenantId);
        return true;
    }


    /**
     * 用于在完成请求和响应后执行操作
     * @param request       请求
     * @param response      响应
     * @param handler       对象
     * @param ex            异常
     * @throws Exception    抛出异常
     */
    @Override
    public void afterCompletion(@Nonnull HttpServletRequest request,
                                @Nonnull HttpServletResponse response,
                                @Nonnull Object handler,
                                @Nullable Exception ex) throws Exception {

        //清除多租户
        TenantContextHolder.removeLocalTenantId();
        //清除微信配置
        WxMaConfigHolder.remove();
        //清除多数据源
        DynamicDataSourceContextHolder.clear();
        //清除线程缓存
        RequestContextHolder.resetRequestAttributes();
    }

}



